#include "../head/client.h"
#include "../head/md5.h"

// 处理用户输入的指令
int handle_cmd(char *cmd, int socket_fd)
{
	train_t train;
	bzero(&train, sizeof(train));

	char *order = strtok(cmd, " ");
	char *path = strtok(NULL, " ");
	char *arg1 = strtok(NULL, " ");
	if (arg1 != NULL)
	{
		printf("Error Arguments!!\n");
		return -1;
	}

	if (!strcmp(order, "cd"))
	{
		if (path == NULL)
			strcpy(path, "~");
		send_str(socket_fd, order);
		send_str(socket_fd, path);
		// 是否cd成功
		bzero(&train, sizeof(train));
		recv(socket_fd, &train.length, sizeof(train.length), MSG_WAITALL);
		recv(socket_fd, train.data, train.length, MSG_WAITALL);
		int cmp = strcmp(train.data, "success");
		if (cmp == 0)
			printf("目录切换成功！\n");
		else
			printf("目录切换失败！您输入的路径不存在！\n");
	}
	else if (!strcmp(order, "pwd"))
	{
		if (path != NULL)
		{
			printf("Error Arguments!\n");
			return -1;
		}
		send_str(socket_fd, order);
		bzero(&train, sizeof(train));
		recv(socket_fd, &train.length, sizeof(train.length), MSG_WAITALL);
		recv(socket_fd, train.data, train.length, MSG_WAITALL);
		puts(train.data); // 打印当前路径
	}
	else if (!strcmp(order, "ls"))
	{
		if (path != NULL)
		{
			printf("Error Arguments!\n");
			return -1;
		}
		send_str(socket_fd, order);

		bzero(&train, sizeof(train));
		recv(socket_fd, &train.length, sizeof(train.length), MSG_WAITALL);
		if (train.length == 0) // 空目录
		{
			return 0;
		}
		recv(socket_fd, train.data, train.length, MSG_WAITALL);
		// 打印当前目录下的所有文件名
		char *p;
		for (p = strtok(train.data, "/"); p != NULL; p = strtok(NULL, "/"))
		{
			printf("%s  ", p);
		}
		printf("\n");
	}
	else if (!strcmp(order, "puts"))
	{
		if (path == NULL)
		{
			printf("Error Arguments!\n");
			return -1;
		}

		int file_fd = open(path, O_RDONLY);
		ERROR_CHECK(file_fd, -1, "open");

		char md5_str[MD5_STR_LEN + 1];
		compute_file_md5(file_fd, md5_str);
		lseek(file_fd, 0, SEEK_SET);

		// 文件名字需要从path中截取
		char filename[1024] = {0};
		int i;
		for (i = strlen(path) - 1; i > 0; i--)
		{
			if (path[i] == '/') // 路径从后往前第一个'/'
				break;
		}
		if (i)
			strcpy(filename, (path + i + 1));
		else // i==0,意味path存的就是个文件名
			strcpy(filename, path);
		printf("需要上传文件的名字：%s\n", filename);

		// 发送puts指令、文件名、md5加密hash给服务器
		send_str(socket_fd, order);
		send_str(socket_fd, filename);
		send_str(socket_fd, md5_str);

		// 接收服务器的确认信息，判断要上传的文件是否存在
		bzero(&train, sizeof(train));
		recv(socket_fd, &train.length, sizeof(train.length), MSG_WAITALL);
		if (train.length == 0) // 服务器中已经存在该文件了
		{
			printf("极速上传成功！\n");
			close(file_fd);
			return 0;
		}
		else if (train.length == -1)
		{
			printf("服务器故障！\n");
			close(file_fd);
			return 0;
		}

		printf("上传中...\n");
		send_file(socket_fd, file_fd);
		printf("上传成功！\n");
		close(file_fd);
	}
	else if (!strcmp(order, "gets"))
	{
		if (path == NULL)
		{
			printf("Error Arguments!\n");
			return -1;
		}
		send_str(socket_fd, order);
		send_str(socket_fd, path);

		// 接收服务器的确认信息，判断要下载的文件是否存在
		bzero(&train, sizeof(train));
		recv(socket_fd, &train.length, sizeof(train.length), MSG_WAITALL);
		if (train.length == 0) // 服务器中不存在该文件
		{
			printf("文件不存在!\n");
			return -1;
		}

		// 文件名字需要从path中截取
		char filename[1024] = {0};
		int i;
		for (i = strlen(path) - 1; i > 0; i--)
		{
			if (path[i] == '/') // 路径从后往前第一个'/'
				break;
		}
		if (i)
			strcpy(filename, (path + i + 1));
		else // i==0,意味path存的就是个文件名
			strcpy(filename, path);
		printf("需要下载文件的名字：%s\n", filename);

		// 断点下载
		bzero(&train, sizeof(train));
		int acs_ret = access(filename, F_OK);
		int file_fd;
		if (acs_ret == 0) // 需要下载的文件已经存在
		{
			file_fd = open(filename, O_RDWR | O_APPEND);
			ERROR_CHECK(file_fd, -1, "open");
			struct stat statbuf;
			fstat(file_fd, &statbuf);
		
			// 告诉服务器目前已存在的文件的大小
			send(socket_fd, &statbuf.st_size, sizeof(off_t), MSG_NOSIGNAL);
			// lseek(file_fd, statbuf.st_size, SEEK_SET);
		}
		else // 新建文件到./client/source/目录下
		{
			file_fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0666);
			ERROR_CHECK(file_fd, -1, "open");
			// 告诉服务器目前已存在的文件的大小
			off_t file_size = 0;
			send(socket_fd, &file_size, sizeof(off_t), MSG_NOSIGNAL);
		}

		printf("下载中...\n");
		recv_file(socket_fd, file_fd);
		printf("下载成功！\n");
		close(file_fd);
	}
	else if (!strcmp(order, "remove"))
	{
		if (path == NULL)
		{
			printf("Error Arguments!\n");
			return -1;
		}
		send_str(socket_fd, order);
		send_str(socket_fd, path);
		// 是否删除成功
		bzero(&train, sizeof(train));
		recv(socket_fd, &train.length, sizeof(train.length), MSG_WAITALL);
		recv(socket_fd, train.data, train.length, MSG_WAITALL);
		int cmp = strcmp(train.data, "success");
		if (cmp == 0)
			printf("删除文件成功！\n");
		else
			printf("删除文件失败！文件不存在！\n");
	}
	else
	{
		printf("输入了错误的指令!\n");
		return -1;
	}

	return 0;
}
